/**
 * @widoc $.fn.initFilter
 * @namespace comp
 * @des 初始化关键字过滤元素，该元素为 input[type="text"] 或 textarea
 * @type function
 * @param {object} opts 配置参数
 * @param {Array=} opts.data 要进行过滤的数据源
 * @param {string|Array} opts.fields 要过滤的字段的属性名
 * @param {boolean|Array} opts.pySupport 是否支持拼音首字过滤，默认为：true。当以数组定义时，数组的项指定支持首字母搜索的字段名，只作用于 opts.fields 中定义的字段。
 * @param {string=} opts.placeholder 搜索框占位符(不支持IE8,9)
 * @param {function=} opts.afterFilter(newData,keyword) 过滤完成后的回调方法
 *   - {Array} newData:过滤后的数据
 *   - {string} keyword:当前的过滤关键字
 * @return {object} obj 返回对象
 * @rtn {function} obj.fSetEnable(enable) 启用/禁用过滤
 *   - {boolean=} enable 是否启用，默认为：true。
 * @rtn {function} obj.filter(val) 手动过滤，不会引起回调。
 *   - {string} val 关键字
 * @rtn {function} obj.setData(data) 重置过滤源数据，关键字将还原为 ''，结果数组将还原为 []。
 *   - {Array} data 过滤数据源。<p class="t_red">注意：移除原来的第二个参数 keyword，需要时可以调用 obj.filter(keyword)。</p>
 * @rtn {function} obj.fGetResultData() 获取过滤后的数据。
 * @rtn {function} obj.getFilterData() <span class="t_gray80">请用 obj.fGetResultData() 替代。</span>
 */
$.fn.initFilter = function(opts){
    var el = $(this),
        api;
    opts = $.extend({
        //data:[],// 要搜索的数据源
        fields: 'name',
        placeholder: '',//搜索框占位符
        pySupport: true,// 拼音首字支持
        afterFilter: $.noop// function(newData,keyword)// 过滤完成后的回调函数，newData:过滤后的数据
    }, opts);
    var aSrcData,// 过滤数据源
        aDictData,// 根据数据源生成的过滤字段字典
        sKeyword,// 过滤关键字
        aResultData,// 过滤后的数据
        bEnable;// 是否启用
    // 根据关键字搜索数据源
    var fFilter = function(val, doCb){
        var oldVal = sKeyword;
        if(!aSrcData || !aSrcData.length){// 没有数据源
            return;
        }
        if(el.val() != val){
            el.val(val);// 更新搜索框文本
        }
        sKeyword = val.toLocaleUpperCase();
        if(sKeyword === oldVal) return;// 关键字未发生变化
        if(sKeyword == ''){// 关键字为空，返回全部
            aResultData = aSrcData;
        }
        else{
            aResultData = [];
            for(var i = 0, vals; i < aSrcData.length; i++){
                vals = aDictData[i];
                for(var j = 0; j < vals.length; j++){
                    if(vals[j].toLocaleUpperCase().indexOf(sKeyword) != -1){
                        aResultData.push(aSrcData[i]);
                        break;
                    }
                }
            }
        }
        doCb && opts.afterFilter(aResultData, sKeyword);
    };
    // 根据数据源生成对应的过滤字段字典 - 可能由重置数据源、过滤字段、首字母配置而发生变化
    var fResetDictData = function(){
        // 字典变化会导致过滤结果变化，先将关键字、字典数组、结果数组还原
        sKeyword = '';
        el.val(sKeyword);
        aResultData = aSrcData;
        aDictData.length = 0;
        if(aSrcData){
            var fields = opts.fields,
                pySupport = opts.pySupport,
                aPySupport;// 多字段过滤时，opts.fields 中每个字段对应的 pySupport
            var len = aSrcData.length,
                i, item, val, filterVals,
                bPySupport, flen;// pySupport 为数组时的循环临时变量
            if(Object.prototype.toString.call(fields) === '[object Array]'){
                aPySupport = [];
                flen = fields.length;
                // 记录 fields 中每个字段对应的 pySupport
                if(Object.prototype.toString.call(pySupport) == '[object Array]'){
                    for(i = 0; i < flen; i++){
                        aPySupport[i] = pySupport.indexOf(fields[i]) != -1;
                    }
                }
                else{
                    for(i = 0; i < flen; i++){
                        aPySupport[i] = pySupport;
                    }
                }
                for(i = 0; i < len; i++){
                    filterVals = [];
                    item = aSrcData[i];
                    for(var f = 0; f < fields.length; f++){
                        val = item[fields[f]];
                        var vType = typeof val;
                        if(vType == 'boolean' || vType == 'string' || vType == 'number'){
                            val = String(item[fields[f]]).toLocaleUpperCase();
                            filterVals.push(val);
                            if(aPySupport[f] && /[\u4e00-\u9fa5]+/.test(val)){
                                filterVals = filterVals.concat($.makePyArr(val));
                            }
                        }
                    }
                    aDictData.push(filterVals);
                }
            }
            else{
                bPySupport = Object.prototype.toString.call(pySupport) == '[object Array]'
                    ? pySupport.indexOf(fields) != -1
                    : pySupport;
                for(i = 0; i < len; i++){
                    filterVals = [];
                    val = aSrcData[i][fields].toLocaleUpperCase();
                    filterVals.push(val);
                    if(bPySupport && /[\u4e00-\u9fa5]+/.test(val)){
                        filterVals = filterVals.concat($.makePyArr(val));
                    }
                    aDictData.push(filterVals);
                }
            }
        }
    };
    // 设置数据源
    var fSetSrcData = function(data/*, val, doCb*/){
        // 2017.11.16 by qq 不需要引起过滤，应用场景中未发现传入 val 及 doCb，需要时可以调用 api.filter
        // - 删除参数 val, doCb
        // - 移除最后一行 fFilter()
        aSrcData = $.extend([], data);
        fResetDictData();// 关键字、结果数组在重置字典表时还原
        //fFilter(val || '', doCb);
    };
    // 获取数据源
    var fGetSrcData = function(){
        return aSrcData;
    };
    // 获取当前关键字过滤后的数据
    var fGetResultData = function(){
        return aResultData;
    };
    // 过滤框键盘抬起触发过滤
    var fOnInputKeyup = function(){
        var val = el.val();
        if(val != sKeyword){
            fFilter(val, true);
        }
    };
    // 启用/禁用过滤功能，绑定 keyup 事件，默认启用
    var fSetEnable = function(enable){
        el.off('keyup.wiFilter');
        bEnable = enable = enable !== false;
        if(enable){
            el.on('keyup.wiFilter', fOnInputKeyup);
        }
    };
    // 重设配置
    var fReset = function(cusOpts){
        var bPySupportChanged;// 首字母支持是否发生变化
        if(cusOpts){
            bPySupportChanged = typeof cusOpts.pySupport != 'undefined' && cusOpts.pySupport != opts.pySupport;
            $.extend(opts, cusOpts);

            if(cusOpts.data){
                fSetSrcData(cusOpts.data);// 重新记录数据并生成字典数组
            }
            else if(cusOpts.fields || bPySupportChanged){
                fResetDictData();// 重新生成字典数组
            }
            // afterFilter - 过滤时自动生效，不需要在 fReset 中处理
        }
        else{// 初始化时，处理 opts
            fSetSrcData(opts.data);
        }
        el.attr('placeholder', opts.placeholder);
    };
    var fInit = function(){
        aDictData = [];
        fReset();
        fSetEnable();// 启用过滤
    };
    api = {
        fReset: fReset,
        fSetEnable: fSetEnable,// 启用/禁用过滤
        fGetResultData: fGetResultData,// 获取过滤后的数据
        filter: fFilter,// 根据关键字过滤
        setData: fSetSrcData,// 更新数据源
        getData: fGetSrcData,// 获取数据源 - TODO 暂未发现开放的必要场景
        getFilterData: fGetResultData// 获取过滤后的数据
    };
    fInit();
    return api;
};